import { useEffect, useRef } from 'react';
import { setStorageItem } from '../utils/storage';
import { useHashChange } from './useHashChange';
import type { TodosFilter, TodoItem } from '../machines/todosMachine';
import { TodosContext } from '../contexts/todo';

export function useTodosActions() {
  const todosActorRef = TodosContext.useActorRef();
  const { send } = todosActorRef;
  const todo = TodosContext.useSelector((s) => s.context.todo);
  const todos = TodosContext.useSelector((s) => s.context.todos);
  const filter = TodosContext.useSelector((s) => s.context.filter);

  // Persist todos
  useEffect(() => {
    todosActorRef.subscribe(() => {
      setStorageItem(
        'todos',
        todosActorRef.getPersistedSnapshot?.()
      );
    });
  }, [todosActorRef]);

  useHashChange(() => {
    send({
      type: 'filter.change',
      filter: (window.location.hash.slice(2) || 'all') as TodosFilter
    });
  });

  // Capture initial state of browser hash
  useEffect(() => {
    if (window.location.hash.slice(2)) {
      send({
        type: 'filter.change',
        filter: window.location.hash.slice(2) as TodosFilter
      });
    }
  }, [send]);

  const numActiveTodos = todos.filter((todo) => !todo.completed).length;
  const allCompleted = todos.length > 0 && numActiveTodos === 0;
  const mark = !allCompleted ? 'completed' : 'active';
  const filteredTodos = filterTodos(filter, todos);
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    if (todos.length === 0) {
      inputRef.current?.focus();
    }
  }, [todos]);

  return {
    send,
    todo,
    todos,
    filter,
    numActiveTodos,
    allCompleted,
    mark,
    filteredTodos,
    inputRef
  };
}

function filterTodos(filter: TodosFilter, todos: TodoItem[]) {
  if (filter === 'active') {
    return todos.filter((todo) => !todo.completed);
  }

  if (filter === 'completed') {
    return todos.filter((todo) => todo.completed);
  }

  return todos;
}
